package com.vx.ratingTool.match;

import java.util.List;
import java.util.Random;

import com.vx.ratingTool.Player;

public class Match {
	private List<Player> teamA;
	private List<Player> teamB;
	private int teamArating;
	private int teamBrating;
	private int teamAskill;
	private int teamBskill;
	private Boolean teamAwins;
	private int chanceToWinOfTeamAInPercent;
	private int chanceToWinOfTeamABasedOnRatingPercent;

	public Match(List<Player> teamA, List<Player> teamB) {
		super();
		this.setTeamA(teamA);
		this.setTeamB(teamB);
		teamArating = 0;
		teamBrating = 0;
		teamAskill = 0;
		teamBskill = 0;
		for (int j = 0; j < 5; j++) {
			teamArating += teamA.get(j).getRating();
			teamBrating += teamB.get(j).getRating();
			teamAskill += teamA.get(j).getSkill();
			teamBskill += teamB.get(j).getSkill();
		}
	}

	public void Simulate() {
		// calculate team A chance of winning based on skill
		// base 50% = 500
		// skill of A = 100 points of skill diff = 100% chance of winning
		int chanceToWinOfTeamA = 500 + (teamAskill - teamBskill) * 5;
		chanceToWinOfTeamAInPercent = (int) chanceToWinOfTeamA / 10;
		if (chanceToWinOfTeamAInPercent > 100)
			chanceToWinOfTeamAInPercent = 100;
		if (chanceToWinOfTeamAInPercent < 0)
			chanceToWinOfTeamAInPercent = 0;
		// roll a dice
		Random rndRandom = new Random();
		if (rndRandom.nextInt(1000) < chanceToWinOfTeamA) {
			teamAwins = true;
		} else
			teamAwins = false;
		// calculate winning team's rating boost based on player rating -
		// opposing team rating
		int ratingDiff = teamArating - teamBrating;
		boolean teamAisLikelyToWin = false;
		boolean equalChances = true;
		if (ratingDiff < 0) {
			equalChances = false;
			teamAisLikelyToWin = false;
		} else if (ratingDiff > 0) {
			equalChances = false;
			teamAisLikelyToWin = true;
		}

		int chanceToWinOfTeamABasedOnRating = 500 + (teamArating - teamBrating) / 5;
		chanceToWinOfTeamABasedOnRatingPercent = chanceToWinOfTeamABasedOnRating / 10;
		if (equalChances) {
			// rating +/- 20
			if (teamAwins)
				for (int i = 0; i < teamA.size(); i++) {
					teamA.get(i).setLastRatingChange(20);
					teamB.get(i).setLastRatingChange(-20);
				}
			else {
				for (int i = 0; i < teamB.size(); i++) {
					teamA.get(i).setLastRatingChange(-20);
					teamB.get(i).setLastRatingChange(20);
				}
			}
		} else if (teamAisLikelyToWin & teamAwins) {
			// team A gets with chance 52% = (1-0.52)*1.8*20
			// team B gets with chance 48% = -(0.52)*2.3*20
			for (int i = 0; i < teamA.size(); i++) {
				teamA.get(i).setLastRatingChange((int) Math.floor((double) (chanceToWinOfTeamABasedOnRating) / 1000 * 1.8 * 20));
				teamB.get(i).setLastRatingChange((int) Math.floor((double) (chanceToWinOfTeamABasedOnRating) / 1000 * 1.8 * (-20)));
			}
		} else if (!teamAisLikelyToWin & teamAwins) {
			// team A gets with chance 48% = (1-0.48)*2.3*20
			// team B gets with chance 52% = -(0.48)*1.8*20
			for (int i = 0; i < teamA.size(); i++) {
				teamA.get(i).setLastRatingChange((int) Math.floor((double) (chanceToWinOfTeamABasedOnRating) / 1000 * 2.3 * 20));
				teamB.get(i).setLastRatingChange((int) Math.floor((double) (chanceToWinOfTeamABasedOnRating) / 1000 * 2.3 * (-20)));
			}
		} else if (teamAisLikelyToWin & !teamAwins) {
			// team B gets with chance 48% = (0.52)*2.3*20
			// team A gets with chance 52% = -(1-0.52)*1.8*20
			for (int i = 0; i < teamA.size(); i++) {
				teamB.get(i).setLastRatingChange((int) Math.floor((double) (chanceToWinOfTeamABasedOnRating) / 1000 * 2.3 * 20));
				teamA.get(i).setLastRatingChange((int) Math.floor((double) (chanceToWinOfTeamABasedOnRating) / 1000 * 2.3 * (-20)));
			}
		} else if (!teamAisLikelyToWin & !teamAwins) {
			// team B gets with chance 52% = (0.48)*1.8*20
			// team A gets with chance 48% = -(1-0.48)*2.3*20
			for (int i = 0; i < teamA.size(); i++) {
				teamB.get(i).setLastRatingChange((int) Math.floor((double) (chanceToWinOfTeamABasedOnRating) / 1000 * 1.8 * 20));
				teamA.get(i).setLastRatingChange((int) Math.floor((double) (chanceToWinOfTeamABasedOnRating) / 1000 * 1.8 * (-20)));
			}
		}

		// wins/losses and streak rating increase
		if (teamAwins) {
			for (int i = 0; i < teamA.size(); i++) {

				teamA.get(i).setWins(teamA.get(i).getWins() + 1);

				if (teamA.get(i).getWinsInARow() <= 0)
					teamA.get(i).setWinsInARow(1);
				else
					teamA.get(i).setWinsInARow(teamA.get(i).getWinsInARow() + 1);

				if (teamB.get(i).getWinsInARow() >= 0)
					teamB.get(i).setWinsInARow(-1);
				else
					teamB.get(i).setWinsInARow(teamB.get(i).getWinsInARow() - 1);

				teamA.get(i).setLastRatingChange((int) (teamA.get(i).getLastRatingChange() * teamA.get(i).getWinsInARow() * 0.8));
				teamB.get(i).setLastRatingChange((int) (teamB.get(i).getLastRatingChange() * (-teamB.get(i).getWinsInARow() * 0.8)));
			}
		}
		if (!teamAwins) {
			for (int i = 0; i < teamB.size(); i++) {

				teamB.get(i).setWins(teamB.get(i).getWins() + 1);

				if (teamB.get(i).getWinsInARow() <= 0)
					teamB.get(i).setWinsInARow(1);
				else
					teamB.get(i).setWinsInARow(teamB.get(i).getWinsInARow() + 1);

				if (teamA.get(i).getWinsInARow() >= 0)
					teamA.get(i).setWinsInARow(-1);
				else
					teamA.get(i).setWinsInARow(teamA.get(i).getWinsInARow() - 1);

				teamB.get(i).setLastRatingChange((int) (teamB.get(i).getLastRatingChange() * teamB.get(i).getWinsInARow() * 0.8));
				teamA.get(i).setLastRatingChange((int) (teamA.get(i).getLastRatingChange() * (-teamA.get(i).getWinsInARow() * 0.8)));

			}
		}

		// placement matches + change rating + games played++
		for (int i = 0; i < teamA.size(); i++) {
			if (teamA.get(i).getPlacementLeft() > 0) {
				teamA.get(i).setLastRatingChange(teamA.get(i).getLastRatingChange() * 10);
				teamA.get(i).setPlacementLeft(teamA.get(i).getPlacementLeft() - 1);
			}
			teamA.get(i).setRating(teamA.get(i).getRating() + teamA.get(i).getLastRatingChange());

			if (teamB.get(i).getPlacementLeft() > 0) {
				teamB.get(i).setLastRatingChange(teamB.get(i).getLastRatingChange() * 10);
				teamB.get(i).setPlacementLeft(teamB.get(i).getPlacementLeft() - 1);
			}
			teamB.get(i).setRating(teamB.get(i).getRating() + teamB.get(i).getLastRatingChange());

			teamA.get(i).setGamesPlayed(teamA.get(i).getGamesPlayed() + 1);
			teamB.get(i).setGamesPlayed(teamB.get(i).getGamesPlayed() + 1);

		}
	}

	public List<Player> getTeamA() {
		return teamA;
	}

	public void setTeamA(List<Player> teamA) {
		this.teamA = teamA;
	}

	public List<Player> getTeamB() {
		return teamB;
	}

	public void setTeamB(List<Player> teamB) {
		this.teamB = teamB;
	}

	public int getTeamArating() {
		return teamArating;
	}

	public void setTeamArating(int teamArating) {
		this.teamArating = teamArating;
	}

	public int getTeamBrating() {
		return teamBrating;
	}

	public void setTeamBrating(int teamBrating) {
		this.teamBrating = teamBrating;
	}

	public int getTeamAskill() {
		return teamAskill;
	}

	public void setTeamAskill(int teamAskill) {
		this.teamAskill = teamAskill;
	}

	public int getTeamBskill() {
		return teamBskill;
	}

	public void setTeamBskill(int teamBskill) {
		this.teamBskill = teamBskill;
	}

	public Boolean getTeamAwins() {
		return teamAwins;
	}

	public void setTeamAwins(Boolean teamAwins) {
		this.teamAwins = teamAwins;
	}

	public int getChanceToWinOfTeamAInPercent() {
		return chanceToWinOfTeamAInPercent;
	}

	public int getChanceToWinOfTeamABasedOnRatingPercent() {
		return chanceToWinOfTeamABasedOnRatingPercent;
	}
}
